package com.github.ghsea.framework.job.service;

import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.github.ghsea.framework.job.common.TriggerMetadata;
import com.github.ghsea.framework.job.common.exception.JobRegistryException;
import com.github.ghsea.framework.job.core.JobKey;
import com.github.ghsea.framework.job.core.JobServerKey;
import com.github.ghsea.framework.job.dao.JobAssignmentDao;
import com.github.ghsea.framework.job.dao.TriggerMetadataDao;
import com.github.ghsea.framework.job.loadbalancer.JobServerSelector;
import com.github.ghsea.framework.job.module.JobAssignment;

@Component
public class JobRegistryServiceImpl implements JobRegistryService {

	@Autowired
	private TriggerMetadataDao triggerMetaDao;

	@Autowired
	private JobServerSelector serverSelector;

	@Autowired
	private JobAssignmentDao assignmentDao;

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void register(TriggerMetadata trigger) throws JobRegistryException {
		String appName = trigger.getAppName();
		String jobName = trigger.getJobName();
		JobKey jobKey = new JobKey(appName, jobName);
		TriggerMetadata dbTriggerMeta = triggerMetaDao.findByJobKey(jobKey);
		if (dbTriggerMeta == null) {
			triggerMetaDao.insert(trigger);

			JobServerKey serverKey = serverSelector.select(appName, jobName);
			JobAssignment assignment = new JobAssignment();
			assignment.setServerKey(serverKey);
			assignment.setJobKey(jobKey);
			assignment.setCreateTime(new Date());
			// 插入表后，各个JobServer自己查表，找到分配给自己的Job，然后调度
			assignmentDao.insert(assignment);
		} else {
			if (trigger.getVersion() > dbTriggerMeta.getVersion()) {
				update(trigger);
			}
		}
	}

	public void update(TriggerMetadata trigger) {
		String appName = trigger.getAppName();
		String jobName = trigger.getJobName();
		JobKey jobKey = new JobKey(appName, jobName);
		TriggerMetadata dbJob = triggerMetaDao.findByJobKey(jobKey);
		if (trigger.getVersion() > dbJob.getVersion()) {
			triggerMetaDao.update(trigger);

			JobAssignment oldAssignment = assignmentDao.findByJobKey(jobKey);
			oldAssignment.setUpdateTime(new Date());
			// need assign标记为1，需要重新促发schedular
			int updateCnt = assignmentDao.updateByPk(oldAssignment);
			if (updateCnt == 0) {
				// TODO .It shoud not happen

			}
		}
	}

}
